package iit.projects.etaxi.model.service;

import iit.projects.etaxi.model.dao.SubCityDao;
import iit.projects.etaxi.model.dto.SubCitySCDO;
import iit.projects.etaxi.model.entity.City;
import iit.projects.etaxi.model.entity.SubCity;
import iit.projects.etaxi.model.exception.CityNotFoundException;
import iit.projects.etaxi.model.exception.DuplicateSubCityException;
import iit.projects.etaxi.util.Constants;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Transactional(readOnly = true)
public class SubCityServiceImpl implements SubCityService {
	
	final Logger log = LoggerFactory.getLogger(SubCityServiceImpl.class);
	
	private SubCityDao subCityDao;
	
	private CityService cityService;

	@Override
	@Transactional( readOnly=false, propagation=Propagation.REQUIRES_NEW)
	public void deleteSubCity(SubCity subCity) throws CityNotFoundException {
		
		subCityDao.deleteSubCity(subCity);
	}

	@Override
	public Set<SubCity> findSubCities(SubCitySCDO subCitySCDO) {
		return subCityDao.findSubCities(subCitySCDO);
	}

	@Override
	@Transactional( readOnly=false, propagation=Propagation.REQUIRES_NEW, 
			rollbackFor={DuplicateSubCityException.class, CityNotFoundException.class})
	public SubCity saveSubCity(String cityCode, SubCity subCity) throws DuplicateSubCityException, CityNotFoundException {
	
		City city = cityService.findByPrimaryKey(cityCode);
		subCity.setCity(city);
		
		return subCityDao.addSubCity(subCity);
	}

	@Override
	@Transactional( readOnly=false, propagation=Propagation.REQUIRES_NEW, 
			rollbackFor={CityNotFoundException.class})
	public SubCity updateSubCity(String cityCode, SubCity subCity) throws CityNotFoundException {
		City city = cityService.findByPrimaryKey(cityCode);
		subCity.setCity(city);
		
		return subCityDao.updateSubCity(subCity);
	}
	
	@Override
	@Transactional( readOnly=false, propagation=Propagation.REQUIRES_NEW)
	public Set<SubCity> setProximity(SubCity selectedSubCity, SubCity closeSubCity){
		
		Set<SubCity> savedCollection = new HashSet<SubCity>();
		if(log.isDebugEnabled()){
			log.debug("Going to assign Proximity of " + selectedSubCity.getName() + 
					" and " + closeSubCity.getName());
		}
		Map<String, SubCity> savedSubCities = subCityDao.setProximity(selectedSubCity, closeSubCity);

		savedCollection.add(savedSubCities.get(Constants.SELECTED_SUBCITY));
		savedCollection.add(savedSubCities.get(Constants.CLOSE_BY_SUBCITY));

		return savedCollection;
	}
	
	@Override
	@Transactional( readOnly=false, propagation=Propagation.REQUIRES_NEW)
	public Map<String, SubCity> removeProximity(SubCity selectedSubCity, SubCity removingSubCity){
		return subCityDao.removeProximity(selectedSubCity, removingSubCity);
	}
	
	public void setSubCityDao(SubCityDao subCityDao) {
		this.subCityDao = subCityDao;
	}

	public void setCityService(CityService cityService) {
		this.cityService = cityService;
	}

}
